/**
 * QuestionUtil.java
 * com.sftz.assets.utils
 * Copyright (c) 2018, 北京科技有限公司版权所有.
*/

package com.sftz.assets.utils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.sftz.assets.entities.question.PaperAnswerInfoEntity;
import com.sftz.assets.entities.question.PaperEntity;
import com.sftz.assets.enums.ExamStartStatusEnum;
import com.sftz.framework.util.ArrayUtil;
import com.sftz.framework.util.DateConvertUtil;
import com.sftz.framework.util.WeappHtmlUtil;
import com.sftz.modules.common.dto.FillCountDto;
import com.sftz.modules.common.dto.FillInStemDto;
import com.uxuexi.core.common.util.DateUtil;
import com.uxuexi.core.common.util.Util;

/**
 * 
 * 试题工具,提供客观题判卷等操作
 *
 * @author   朱晓川
 * @Date	 2018年12月29日 	 
 */
public class QuestionUtil {

	//一分钟的秒数
	public static final int SECONDS_OF_MINUTE = 60;

	/**
	 * 图片上传类型
	 */
	public static final int UPLOAD_TYPE_IMG = 1;

	/**
	 * 文件上传类型
	 */
	public static final int UPLOAD_TYPE_FILE = 2;

	/**
	 * 视频上传类型
	 */
	public static final int UPLOAD_TYPE_VIDEO = 3;

	//逗号
	private static String COMMA = ",";
	//填空题答案分隔符
	private static String FILLIN_SPLITER = "##";

	//填空题答案分隔符-用于页面显示
	private static String SHOW_SPLITER = ";";

	//填空题题干用于页面展示的替换字符串
	private static String STEM_SHOW_SPLITER = "____";

	//填空题题干用于存储到数据库中的标签
	private static String STEM_STORAGE_SPLITER = "<input type='text' class='fillVacancy' value=''/>";

	//代表填空题'空'的html标签名
	private static String FILLIN_TAGNAME = "input";

	private QuestionUtil() {
	}

	/**
	 * 客观题是否回答正确
	 * <p>
	 * 客观题的答案都是逗号拼接选项id的字符串
	 * 
	 * @param answerOption   试题的答案
	 * @param answerContent  用户的答案
	 */
	public static boolean objectiveCorrect(String answerOption, String answerContent) {

		//未作答
		if (Util.isEmpty(answerContent)) {
			return false;
		}

		if (Util.isEmpty(answerOption)) {
			throw new IllegalArgumentException("答案不能为空");
		}

		if (answerOption == answerContent) {
			return true;
		}

		String[] opts = answerOption.split(COMMA);
		String[] contents = answerContent.split(COMMA);
		boolean flag = ArrayUtil.isEquals(opts, contents);
		if (flag) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 填空题题干处理
	 * <p>
	 * 将题干中的input标签替换为'____',用于页面展示
	 */
	public static FillInStemDto fillInStemReplace(String stem, String answerContent) {
		String stemNew = stem;
		List<FillCountDto> fillList = new ArrayList<>();
		if (!Util.isEmpty(stem)) {
			String regex = WeappHtmlUtil.HTML_PREFIX + FILLIN_TAGNAME + WeappHtmlUtil.HTML_SUFFIX;
			Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
			Matcher m = pattern.matcher(stem);
			StringBuffer sb = new StringBuffer("");
			while (m.find()) {
				FillCountDto fill = new FillCountDto();
				fill.setContent("");
				fillList.add(fill);
				m.appendReplacement(sb, STEM_SHOW_SPLITER);
			}
			m.appendTail(sb);
			stemNew = sb.toString();
		}

		if (!Util.isEmpty(answerContent)) {
			Document doc = Jsoup.parseBodyFragment(answerContent);
			Elements answerInputs = doc.getElementsByTag(FILLIN_TAGNAME);
			if (!Util.isEmpty(fillList) && !Util.isEmpty(answerInputs)) {
				int fCount = fillList.size();
				int aCount = answerInputs.size();
				if (fCount != aCount) {
					throw new IllegalArgumentException("填空题空的个数和答案空的个数不一致，请检查");
				}

				fillList.clear();
				for (Element one : answerInputs) {
					String value = one.attr("value");

					FillCountDto fill = new FillCountDto();
					fill.setContent(value);
					fillList.add(fill);
				}

			}
		}

		FillInStemDto re = new FillInStemDto();
		re.setStem(stemNew);
		re.setFillList(fillList);
		return re;
	}

	/**
	 * 
	 * 处理填空题用户的答案
	 * <p>
	 * 将页面传递的答案分割后替换到题干中,整体保存为答案
	 */
	public static String fillInAnswerContent(String stem, String answerContent) {
		String re = answerContent;

		if (!Util.isEmpty(answerContent)) {
			List<String> fillList = new ArrayList<>();
			if (answerContent.endsWith(FILLIN_SPLITER)) {
				String an = answerContent.substring(0, answerContent.lastIndexOf(FILLIN_SPLITER));
				//用户的答案
				fillList = Splitter.on(FILLIN_SPLITER).splitToList(an);
			}

			if (!Util.isEmpty(stem)) {
				Document doc = Jsoup.parseBodyFragment(stem);
				Elements stemInputs = doc.getElementsByTag(FILLIN_TAGNAME);
				if (!Util.isEmpty(fillList) && !Util.isEmpty(stemInputs)) {
					int fCount = fillList.size();
					int aCount = stemInputs.size();
					if (fCount != aCount) {
						throw new IllegalArgumentException("填空题空的个数和答案空的个数不一致，请检查");
					}

					for (int i = 0; i < stemInputs.size(); i++) {
						Element input = stemInputs.get(i);
						String value = fillList.get(i);
						input.attr("value", value);
					}
				}
				re = doc.body().html();
			}
		}
		return re;
	}

	/**
	 * 将页面填空题题干中的____替换为input标签，用于存储到数据库
	 */
	public static String getStem4Storage(String stem) {
		if (!Util.isEmpty(stem)) {
			return stem.replaceAll(STEM_SHOW_SPLITER, STEM_STORAGE_SPLITER);
		}
		return stem;
	}

	/**
	 * 还原填空题的答案,用于页面展示
	 */
	public static String restoreFillinAnswer(String answer) {
		if (!Util.isEmpty(answer)) {
			return answer.replaceAll(FILLIN_SPLITER, ";");
		}
		return answer;
	}

	/**
	 * 还原填空题用户的答案,用于页面展示
	 */
	public static String restoreFillinAnswerContent(List<FillCountDto> fillList) {
		if (!Util.isEmpty(fillList)) {
			List<String> fills = Lists.transform(fillList, new Function<FillCountDto, String>() {
				@Override
				public String apply(FillCountDto input) {
					return input.getContent();
				}
			});
			return Joiner.on(SHOW_SPLITER).useForNull("-").join(fills);
		}
		return "";
	}

	/**
	 * 答题结果标准化
	 * <p>
	 * undefined to ""
	 */
	public static String answerNormalize(String answerContent) {
		if ("undefined".equals(answerContent)) {
			return "";
		} else {
			return answerContent;
		}
	}

	/**
	 * 设置开始状态
	 *
	 * @param startDate  作业/试卷的开始时间
	 * @param endDate    作业/试卷的截止时间
	 */
	public static int startStatus(Date startDate, Date endDate, int answerNumber, int recordSize) {
		if (!Util.isEmpty(startDate) && !Util.isEmpty(endDate)) {
			Date now = DateUtil.nowDate();
			int re = ExamStartStatusEnum.NORMAL.intKey();
			if (now.before(startDate)) {
				//未开始
				re = ExamStartStatusEnum.BEFORE.intKey();
			} else if (now.after(endDate)) {
				//已截止
				re = ExamStartStatusEnum.END.intKey();
			}
			if (recordSize >= answerNumber) {
				//作答次数已满
				re = ExamStartStatusEnum.THRESHOLD.intKey();
			}
			return re;
		} else {
			if (startDate.after(endDate)) {
				throw new IllegalArgumentException("非法有效期");
			}
			throw new IllegalArgumentException("有效期不能为空");
		}
	}

	/**
	 * 计算试卷答题记录的截止时间
	 */
	public static Date calAnswerEndTime(PaperEntity paper, PaperAnswerInfoEntity record) {
		if (Util.isEmpty(paper)) {
			throw new IllegalArgumentException("试卷不能为空");
		}

		Date currStartTime = DateUtil.nowDate();
		if (null != record) {
			currStartTime = record.getStartTime();
			if (Util.isEmpty(currStartTime)) {
				throw new IllegalArgumentException("答题开始时间不能为空");
			} else {
				Integer answerTime = paper.getAnswerTime();
				if (Util.isEmpty(answerTime)) {
					throw new IllegalArgumentException("试卷的可作答时间不能为空");
				}
				Integer seconds = SECONDS_OF_MINUTE * answerTime;
				Date answerEndTime = DateConvertUtil.addSeconds(currStartTime, seconds);
				Date endDate = paper.getEndTime();
				if (Util.isEmpty(endDate)) {
					throw new IllegalArgumentException("试卷过期时间不能为空");
				}
				if (endDate.before(answerEndTime)) {
					answerEndTime = endDate;
				}
				return answerEndTime;
			}
		} else {
			throw new IllegalArgumentException("答题记录不能为空");
		}
	}
}
